﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using Hockey.Shared;
using System.Reflection;

namespace Hockey.UILayer.Controls
{
    /// <summary>
    /// Button with arrow for moving compass
    /// TO-DO: make internal
    /// </summary>
    public class ArrowButton: Button
    {
        /// <summary>
        /// Child controls
        /// </summary>
        private Grid _grid;
        private FontAdaptiveTextBlock _number;
        private Arrow _arrow;
        private SquarePanel _sqPanel;
        private SquarePanel _sqPanelNumber;

        // arrow brushes
        private LinearGradientBrush arrBrush;
        private LinearGradientBrush arrBrushDisabled;

        public ArrowButton()
        {
            this.Loaded += ArrowButton_Loaded;
        }

        void ArrowButton_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            BuildButton();
            SetLayout();
        }

        #region Properties

        public string Number
        { get; set; }

        public eArrowPlacement ArrowPlacement
        { get; set; }

        #endregion

        /// <summary>
        /// Builds the button
        /// </summary>
        private void BuildButton()
        {
            this.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Stretch;
            this.VerticalContentAlignment = System.Windows.VerticalAlignment.Stretch;
            // create grid
            _grid = new Grid();
            //_grid.ShowGridLines = true;

            ColumnDefinition col = new ColumnDefinition();
            col.Width = new GridLength(1, GridUnitType.Star);
            _grid.ColumnDefinitions.Add(col);
            col = new ColumnDefinition();
            col.Width = new GridLength(1, GridUnitType.Star);
            _grid.ColumnDefinitions.Add(col);

            RowDefinition row = new RowDefinition();
            row.Height = new GridLength(1, GridUnitType.Star);
            _grid.RowDefinitions.Add(row);
            row = new RowDefinition();
            row.Height = new GridLength(1, GridUnitType.Star);
            _grid.RowDefinitions.Add(row);

            _grid.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
            _grid.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
            this.Content = _grid;

            // create arrow
            arrBrush = new LinearGradientBrush();
            arrBrush.GradientStops.Add(new GradientStop(Colors.Yellow, 0));
            arrBrush.GradientStops.Add(new GradientStop(Colors.Green, 1));
            arrBrush.Freeze();

            arrBrushDisabled = new LinearGradientBrush();
            arrBrushDisabled.GradientStops.Add(new GradientStop(Colors.Orange, 0));
            arrBrushDisabled.GradientStops.Add(new GradientStop(Colors.Red, 1));
            arrBrushDisabled.Freeze();


            _arrow = new Arrow();
            _arrow.Fill = IsEnabled ? arrBrush : arrBrushDisabled;
            _arrow.Stroke = Brushes.Black;
            _arrow.StrokeThickness = 1;
            _arrow.VerticalAlignment = VerticalAlignment.Stretch;
            _arrow.HorizontalAlignment = HorizontalAlignment.Stretch;

            _sqPanel = new SquarePanel();
            _sqPanel.Children.Add(_arrow);
            _grid.Children.Add(_sqPanel);

            // create number textblock
            _sqPanelNumber = new SquarePanel();
            _sqPanelNumber.VerticalAlignment = VerticalAlignment.Stretch;
            _sqPanelNumber.HorizontalAlignment = HorizontalAlignment.Stretch;

            _number = new FontAdaptiveTextBlock();
            _number.Content = Number;
            //_number.VerticalAlignment = VerticalAlignment.Center;
            //_number.HorizontalAlignment = HorizontalAlignment.Center;
            _sqPanelNumber.Children.Add(_number);            
            _grid.Children.Add(_sqPanelNumber);
        }

        /// <summary>
        /// Makes the button look pressed
        /// </summary>
        /// <param name="isPressed"></param>
        public void SetPressed(bool isPressed)
        {
            if (isPressed)
            {
                VisualStateManager.GoToState(this, "Focused", false);
                VisualStateManager.GoToState(this, "PointerFocused", false);
                VisualStateManager.GoToState(this, "Pressed", false);
            }
            else
            {
                VisualStateManager.GoToState(this, "Normal", true);
                VisualStateManager.GoToState(this, "Unfocused", true);
            }
            InvalidateVisual();
        }

        /// <summary>
        /// Creates the button layout
        /// </summary>
        private void SetLayout()
        {
            // set button layout
            var layout = _numberLayout[ArrowPlacement];
            Grid.SetRow(_sqPanelNumber, layout.Row);
            Grid.SetColumn(_sqPanelNumber, layout.Col);
            if (layout.RowSpan.HasValue)
                Grid.SetRowSpan(_sqPanelNumber, layout.RowSpan.Value);
            if (layout.ColSpan.HasValue)
                Grid.SetColumnSpan(_sqPanelNumber, layout.ColSpan.Value);

            // set arrow layout
            layout = _arrowLayout[ArrowPlacement];
            Grid.SetRow(_sqPanel, layout.Row);
            Grid.SetColumn(_sqPanel, layout.Col);
            if (layout.RowSpan.HasValue)
                Grid.SetRowSpan(_sqPanel, layout.RowSpan.Value);
            if (layout.ColSpan.HasValue)
                Grid.SetColumnSpan(_sqPanel, layout.ColSpan.Value);

            var angle = _arrowRotation[ArrowPlacement];
            _arrow.RenderTransform = new RotateTransform(angle);
        }

        /// <summary>
        /// Handling the enabled event for coloring the arrow
        /// </summary>
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if(e.Property.Name == "IsEnabled")
            {
                if (arrBrush != null && arrBrushDisabled != null)
                {
                    // set the arrow brush
                    _arrow.Fill = ((bool)e.NewValue) == true ? arrBrush : arrBrushDisabled;
                }
            }

            base.OnPropertyChanged(e);
        }

        // ArrowButtonRotation
        private Dictionary<eArrowPlacement, double> _arrowRotation = new Dictionary<eArrowPlacement, double>()
        {
            { eArrowPlacement.Top, 0},
            { eArrowPlacement.Bottom, 180},
            { eArrowPlacement.Left, 270},
            { eArrowPlacement.Right, 90},
            { eArrowPlacement.TopLeft, 270+45},
            { eArrowPlacement.TopRight, 45},
            { eArrowPlacement.BottomLeft, 180 + 45},
            { eArrowPlacement.BottomRight, 90 + 45},           
        };

        /// <summary>
        /// Arrow layout
        /// </summary>
        private Dictionary<eArrowPlacement, Placement> _arrowLayout = new Dictionary<eArrowPlacement, Placement>()
        {
            { eArrowPlacement.Top, new Placement() { Row=0, Col=0, RowSpan=null, ColSpan=2}},
            { eArrowPlacement.Bottom, new Placement() {Row=1, Col=0, RowSpan=null, ColSpan=2}},
            { eArrowPlacement.Left, new Placement() { Row=0, Col=0, RowSpan=2, ColSpan=null}},
            { eArrowPlacement.Right, new Placement() {Row=0, Col=1, RowSpan=2, ColSpan=null}},
            { eArrowPlacement.TopLeft, new Placement() { Row=0, Col=0, RowSpan=null, ColSpan=null}},
            { eArrowPlacement.TopRight, new Placement() {Row=0, Col=1, RowSpan=null, ColSpan=null}},
            { eArrowPlacement.BottomLeft, new Placement() {Row=1, Col=0, RowSpan=null, ColSpan=null}},
            { eArrowPlacement.BottomRight, new Placement() {Row=1, Col=1, RowSpan=null, ColSpan=null}},
        };

        /// <summary>
        /// Number layout
        /// </summary>
        private Dictionary<eArrowPlacement, Placement> _numberLayout = new Dictionary<eArrowPlacement, Placement>()
        {
            { eArrowPlacement.Top, new Placement() { Row=1, Col=0, RowSpan=null, ColSpan=2}},
            { eArrowPlacement.Bottom, new Placement() {Row=0, Col=0, RowSpan=null, ColSpan=2}},
            { eArrowPlacement.Left, new Placement() { Row=0, Col=1, RowSpan=2, ColSpan=null}},
            { eArrowPlacement.Right, new Placement() {Row=0, Col=0, RowSpan=2, ColSpan=null}},
            { eArrowPlacement.TopLeft, new Placement() { Row=1, Col=1, RowSpan=null, ColSpan=null}},
            { eArrowPlacement.TopRight, new Placement() {Row=1, Col=0, RowSpan=null, ColSpan=null}},
            { eArrowPlacement.BottomLeft, new Placement() {Row=0, Col=1, RowSpan=null, ColSpan=null}},
            { eArrowPlacement.BottomRight, new Placement() {Row=0, Col=0, RowSpan=null, ColSpan=null}},
        };

        
        /// <summary>
        /// Item Placement Class
        /// </summary>
        private class Placement
        {
            public int Row
            { get; set; }

            public int Col
            { get; set; }

            public int? RowSpan
            { get; set; }

            public int? ColSpan
            { get; set; }
        }
    }
}
